package com.wushijia.highconcurrency.thread;


public class SyncTest {

  public static void main(String args[]) {
    SyncStack2 stack = new SyncStack2();
    Runnable p = new Producer2(stack);
    Runnable c = new Consumer2(stack);
    Thread t1 = new Thread(p);
    Thread t2 = new Thread(c);
    t2.start();
    t1.start();
  }
}


class SyncStack2 {

  private volatile int index = 0;
  private char[] data = new char[6];

  public char[] getData() {
    return data;
  }

  public synchronized void push(char c) {
    if (index == data.length) {
      try {
        this.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    this.notify();
    data[index] = c;
    index++;
  }

  public synchronized char pop() {
    System.out.println(index);
    if (index == 0) {
      try {
        this.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    this.notify();
    index--;
    return data[index];
  }
}


class Producer2 implements Runnable {

  private SyncStack2 stack;

  Producer2(SyncStack2 s) {
    stack = s;
  }

  @Override
  public void run() {
    for (int i = 0; i < 20; i++) {
      char c = (char) (Math.random() * 26 + 'A');
      stack.push(c);
      System.out.println("Produced：" + c);
      try {
        Thread.sleep((int) (Math.random() * 1000));
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}


class Consumer2 implements Runnable {

  private SyncStack2 stack;

  Consumer2(SyncStack2 s) {
    stack = s;
  }

  @Override
  public void run() {
    for (int i = 0; i < 20; i++) {
      char c = stack.pop();
      System.out.println("Consumered：" + c);
      System.out.println(stack.getData());
      try {
        Thread.sleep((int) (Math.random() * 1000));
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

